\input{../slides/common/slides_common}

\newif\ifbook
\input{../shared/chisel}


\title{Customized Circuit Generation}
\author{Martin Schoeberl}
\date{\today}
\institute{Technical University of Denmark}

\begin{document}

\begin{frame}
\titlepage
\end{frame}





\begin{frame}[fragile]{Scala List for Enumeration}
\begin{chisel}
  val empty :: full :: Nil = Enum(2)
\end{chisel}
\begin{itemize}
\item Can be used in wires and registers
\item Symbols for a state machine
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Finite State Machine}
\begin{chisel}
  val empty :: full :: Nil = Enum(2)
  val stateReg = RegInit(empty)
  val dataReg = RegInit(0.U(size.W))

  when(stateReg === empty) {
    when(io.enq.write) {
      stateReg := full
      dataReg := io.enq.din
    }
  }.elsewhen(stateReg === full) {
    when(io.deq.read) {
      stateReg := empty
    }
  }
\end{chisel}
\begin{itemize}
\item A simple buffer for a bubble FIFO
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Parameterization}
\begin{chisel}
class ParamChannel(n: Int) extends Bundle {
  val data = Input(UInt(n.W))
  val ready = Output(Bool())
  val valid = Input(Bool())
}

val ch32 = new ParamChannel(32)
\end{chisel}
\begin{itemize}
\item Bundles and modules can be parametrized
\item Pass a parameter in the constructor
\end{itemize}

\end{frame}
\begin{frame}[fragile]{A Module with a Parameter}
\begin{chisel}
class ParamAdder(n: Int) extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(n.W))
    val b = Input(UInt(n.W))
    val result = Output(UInt(n.W))
  })

  val addVal = io.a + io.b
  io.result := addVal
}

val add8 = Module(new ParamAdder(8))
\end{chisel}
\begin{itemize}
\item Parameter can also be a Chisel type
\item Can also be a generic type:
\item \code{class Mod[T <: Bits](param: T) extends...}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Scala \code{for} Loop for Circuit Generation}
\begin{chisel}
val shiftReg = RegInit(0.U(8.W))

shiftReg(0) := inVal

for (i <- 1 until 8) {
  shiftReg(i) := shiftReg(i-1)
}
\end{chisel}
\begin{itemize}
\item \code{for} is Scala
\item This loop generates several connections
\item The connections are parallel hardware
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Conditional Circuit Generation}
\begin{chisel}
class Base extends Module { val io = new Bundle() }
class VariantA extends Base { }
class VariantB extends Base { }

val m = if (useA) Module(new VariantA())
        else Module(new VariantB())
\end{chisel}
\begin{itemize}
\item \code{if} and \code{else} is Scala
\item \code{if} is an expression that returns a value
\begin{itemize}
\item Like ``\code{cond ? a : b;}'' in C and Java
\end{itemize}
\item This is not a hardware multiplexer
\item Decides which module to generate
\item Could even read an XML file for the configuration
\end{itemize}
\end{frame}

\input{generation.tex}

\begin{frame}[fragile]{Combinational (Truth) Table Generation}
\begin{chisel}
val arr = new Array[Bits](length)
for (i <- 0 until length) {
  arr(i) = ...
}
val rom = Vec[Bits](arr)
\end{chisel}
\begin{itemize}
\item Generate a table in a Scala array
\item Use that array as input for a Chisel \code{Vec}
\item Generates a logic table at hardware construction time
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Ideas for Runtime Table Generation}
\begin{itemize}
\item Assembler in Scala/Java generates the boot ROM
\item Table with a \code{sin} function
\item Binary to BCD conversion
\item Schedule table for a TDM based network-on-chip
\item 
\item More ideas?
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Memory}
\begin{chisel}
val mem = Mem(Bits(width = 8), size)

// write
when(wrEna) {
  mem(wrAddr) := wrData
}

// read
val rdAddrReg = Reg(next = rdAddr)
rdData := mem(rdAddrReg)
\end{chisel}
\begin{itemize}
\item Write is synchronous
\item Read can be asynchronous or synchronous
\item But there are no asynchronous memories in an FPGA
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Factory Methods}
\begin{itemize}
\item Simpler component creation and use
\item Usage similar to built in components, such as \code{Mux}
\end{itemize}
\begin{chisel}
val myAdder = Adder(x, y)
\end{chisel}
\begin{itemize}
\item A little bit more work on component side
\item Define an \code{apply} method on the companion object that returns the component
\end{itemize}
\begin{chisel}
object Adder {
  def apply(a: UInt, b: UInt) = {
    val adder = Module(new Adder)
    adder.io.a := a
    adder.io.b := b
    adder.io.result
  }
}
\end{chisel}
\end{frame}

\begin{frame}[fragile]{Testing and Debugging}
\begin{itemize}
\item Nobody writes perfect code ;-)
\item We need a method to improve the code
\item In Java we can simply print the result:
\begin{itemize}
\item \code{println("42");}
\end{itemize}
\item What can we do in hardware?
\begin{itemize}
\item Describe the whole circuit and hope it works?
\item We can switch an LED on or off
\end{itemize}
\item We need some tools for \href{https://en.wikipedia.org/wiki/Debugging#/media/File:H96566k.jpg}{debugging}
\item Writing testers in Chisel
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Testing with Chisel}
\begin{itemize}
\item Set input values with \code{poke}
\item Advance the simulation with \code{step}
\item Read the output values with \code{peek}
\item Compare the values with \code{expect}
\item Import following packages:
\shortlist{../code/test_import.txt}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Using \code{peek}, \code{poke}, and \code{expect}}
\begin{chisel}
// Set input values
poke(dut.io.a, 3)
poke(dut.io.b, 4)
// Execute one iteration
step(1)
// Print the result
val res = peek(dut.io.result)
println(res)

// Or compare against expected value
expect(dut.io.result, 7)
\end{chisel}
\end{frame}

\begin{frame}[fragile]{A Chisel Tester}
\begin{itemize}
\item Extends class \code{PeekPokeTester}
\item Has the device-under test (DUT) as parameter
\item Testing code can use all features of Scala
\end{itemize}
\begin{chisel}
class CounterTester(dut: Counter) extends PeekPokeTester(dut) {

  // Here comes the Chisel/Scala code
  // for the testing
}
\end{chisel}
\end{frame}

\begin{frame}[fragile]{Example DUT}
\begin{itemize}
\item A device-under test (DUT)
\shortlist{../code/test_dut.txt}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{A Simple Tester}
\begin{itemize}
\item Just using \code{println} for manual inspection
\shortlist{../code/test_bench_simple.txt}
\end{itemize}
\end{frame}


\begin{frame}[fragile]{The Main Program for the Test}
\begin{itemize}
\item Extend an App and invoke the \code{iotesters} driver
\item With the DUT and the tester
\shortlist{../code/test_main_simple.txt}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{A Real Tester}
\begin{itemize}
\item Poke values and \code{expect} some output
\shortlist{../code/test_bench.txt}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{ScalaTest}
\begin{itemize}
\item Testing framework for Scala
\item \code{sbt} understands ScalaTest
\item Run all tests:
\code{sbt test}
\item When all \code{expect}s are ok, the test passes
\item A little bit funny syntax
\item Add library to \code{build.sbt}
\begin{chisel}
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
\end{chisel}
\item Import ScalaTest library
\begin{chisel}
import org.scalatest._
\end{chisel}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{ScalaTest Version of our Tester}
\shortlist{../code/scalatest_simple.txt}
\end{frame}

\begin{frame}[fragile]{Generating Waveforms}
\begin{itemize}
\item Waveforms are timing diagrams
\item Good to see many parallel signals and registers
\item Additional parameters: \code{"--generate-vcd-output", "on"}
\item IO signals and registers are dumped
\item Option \code{--debug} puts all wires into the dump
\item Generates a .vcd file
\item Viewing with GTKWave or ModelSim
\end{itemize}
\end{frame}


\begin{frame}[fragile]{Call the Tester}
\begin{itemize}
\item Using here ScalaTest
\item Note \code{Driver.execute}
\item Note \code{Array("--generate-vcd-output", "on")}
\end{itemize}
\begin{chisel}
class Count6WaveSpec extends
  FlatSpec with Matchers {
  
  "CountWave6 " should "pass" in {
    chisel3.iotesters.Driver.
    execute(Array("--generate-vcd-output", "on"),() => new Count6)
    { c => new Count6Wave(c) }
    should be (true)
  }
}
\end{chisel}
\end{frame}


\begin{frame}[fragile]{Test Driven Development (TDD)}
\begin{itemize}
\item Software development process
\begin{itemize}
\item Can we learn from SW development for HW design?
\end{itemize}
\item Writing the test first, then the implementation
\item Started with extreme programming
\begin{itemize}
\item Frequent releases
\item Accept change as part of the development
\end{itemize}
\item Not used in its pour form
\begin{itemize}
\item Writing all those tests is simply considerer too much work
\end{itemize}
\end{itemize}
\end{frame}


\begin{frame}[fragile]{Testing versus Debugging}
\begin{itemize}
\item Debugging is during code development
\item Waveform and println are easy tools for debugging
\item Debugging does not help for regression tests
\item Write small test cases for regression tests
\item Keeps your code base \emph{intact} when doing changes
\item Better confidence in changes not introducing new bugs
\end{itemize}
\end{frame}



\begin{frame}[fragile]{Summary}
\begin{itemize}
\item Chisel is a small language
\item Embedding it in Scala gives the power
\item We can write circuit generators
\item We can do co-simulation
\item We just scratched the surface
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Links to the Examples}
\begin{itemize}
\item Example code
\end{itemize}
\begin{chisel}
https://github.com/schoeberl/chisel-examples.git
\end{chisel}
\begin{itemize}
\item Slides
\end{itemize}
\begin{chisel}
https://github.com/schoeberl/chisel-book.git
\end{chisel}
\end{frame}

\begin{frame}[fragile]{Feedback}
\begin{itemize}
\item Plans on using Chisel?
\item What went well?
\item What was not so good?
\item How can this Chisel course be improved?
\item
\item Would be happy to receive an email: \code{masca@dtu.dk}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Simulation Lab Session}
\begin{itemize}
\item Testing Hello World
\item Write test/verification code for a 5:1 multiplexer
\item A more interesting tester on an ALU accumulator
\item Project and DUT in GitHub lab1 and lab2
\item \url{https://github.com/chisel-uvm/class2020}
\item Extend it with ScalaTest (see Chisel book)
\end{itemize}
\end{frame}

\begin{frame}[fragile]{FPGA Lab Session}
\begin{itemize}
\item Run and explore the UART (serial port) example
\begin{itemize}
\item There is a make target that builds the UART hardware
\item \code{make uart}
\item It shall write some text out
\item You can observe it with a terminal (e.g., gtkterm)
\end{itemize}
\item Combine the UART with a blinking LED
\begin{itemize}
\item Write a `0' and `1' out on blink off and on
\item Best add the LEDs to \code{UartMain} and \code{uart\_top.vhdl}
\end{itemize}
\item Write repeated numbers 0--9 at maximum speed 
\end{itemize}
\end{frame}

\end{document}

%%%%%%%%%%%%%%%%
\begin{frame}[fragile]{Title}
\begin{chisel}
code
\end{chisel}
\begin{itemize}
\item xxx
\item xxx
\item xxx
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Title}
\begin{itemize}
\item xxx
\item xxx
\item xxx
\item xxx
\item xxx
\end{itemize}
\end{frame}
%%%%%%%%%%%%%%%%

